package com.cb2.algorithm.leetcode;

/**
 * <a href='https://leetcode.cn/problems/defuse-the-bomb'>拆炸弹(Defuse the Bomb)</a>
 * <p>你有一个炸弹需要拆除，时间紧迫！你的情报员会给你一个长度为 n 的 循环 数组 code 以及一个密钥 k 。</p>
 * <p>
 * 为了获得正确的密码，你需要替换掉每一个数字。所有数字会 同时 被替换。
 *     <ul>
 *         <li>如果 k > 0 ，将第 i 个数字用 接下来 k 个数字之和替换。</li>
 *         <li>如果 k < 0 ，将第 i 个数字用 之前的 k 个数字之和替换。</li>
 *         <li>如果 k == 0 ，将第 i 个数字用 0 替换。</li>
 *     </ul>
 * </p>
 * <p>由于 code 是循环的， code[n-1] 下一个元素是 code[0] ，且 code[0] 前一个元素是 code[n-1] 。</p>
 * <p>给你 循环 数组 code 和整数密钥 k ，请你返回解密后的结果来拆除炸弹！</p>
 *
 * <p>
 * <b>示例：</b>
 * <pre>
 *  示例 1：
 *      输入：code = [5,7,1,4], k = 3
 *      输出：[12,10,16,13]
 *      解释：每个数字都被接下来 3 个数字之和替换。解密后的密码为 [7+1+4, 1+4+5, 4+5+7, 5+7+1]。注意到数组是循环连接的。
 *
 *  示例 2：
 *      输入：code = [1,2,3,4], k = 0
 *      输出：[0,0,0,0]
 *      解释：当 k 为 0 时，所有数字都被 0 替换。
 *
 *  示例 3：
 *      输入：code = [2,4,9,3], k = -2
 *      输出：[12,5,6,13]
 *      解释：解密后的密码为 [3+9, 2+3, 4+2, 9+4] 。注意到数组是循环连接的。如果 k 是负数，那么和为 之前 的数字。
 * </pre>
 * </p>
 *
 * <p>
 * <b>提示：</b>
 * <ul>
 *     <li>n == code.length</li>
 *     <li>1 <= n <= 100</li>
 *     <li>1 <= code[i] <= 100</li>
 *     <li>-(n - 1) <= k <= n - 1</li>
 * </ul>
 * </p>
 *
 * @author c2b
 * @since 2025/4/27 17:19
 */
public class LC1652DefuseTheBomb_S {
    static class Solution {
        public int[] decrypt(int[] code, int k) {
            int n = code.length;
            int[] res = new int[n];
            if (k == 0) {
                return res;
            }
            // 第一个窗口的起点
            int firstIdx;
            if (k > 0) {    // k > 0，下一个数是 idx = 1
                firstIdx = 1;
            } else {        // k < 0，下一个数的下标是 code.length  + k
                firstIdx = n + k;
            }
            int sum = 0;
            // 此时形成一个窗口
            for (int i = 0; i < Math.abs(k); i++) {
                sum += code[(firstIdx + i) % n];
            }
            for (int i = 0; i < n; i++) {
                // 更新结果
                res[i] = sum;
                // 移除一个元素
                sum -= code[(firstIdx + i) % n];
                sum += code[(firstIdx + i + Math.abs(k)) % n];
                // 添加一个元素
            }
            return res;
        }
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        Printer.printArrayInt(solution.decrypt(new int[]{5, 7, 1, 4}, 3));
        Printer.printArrayInt(solution.decrypt(new int[]{5, 7, 1, 4}, 0));
        Printer.printArrayInt(solution.decrypt(new int[]{2, 4, 9, 3}, -2));
        Printer.printArrayInt(solution.decrypt(new int[]{5, 2, 4, 9, 3}, 2));
    }
}
